#include <iostream>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;

#define COMMAND_SIZE 1024
#define FORMAT "[%s@%s %s]# "

char* g_argv[COMMAND_SIZE];
int g_argc = 0;

const char* GetUserName()
{
    const char* name = getenv("USER");
    return name == NULL ? "none":name;
}

const char* GetHostName()
{
    const char* name = getenv("HOSTNAME");
    return name == NULL ? "none":name;
}

const char* GetPwd()
{
    const char* name = getenv("PWD");
    return name == NULL ? "none":name;
}
//1.命令行提示符

string DirName(const char* pwd) 
{
#define slash "/"
    string tmp = pwd;
    if(tmp == slash) return slash;
    auto pos = tmp.rfind(slash);
    if(pos == string::npos) return "bug?";
    return tmp.substr(pos+1);
}

void GetPatchLine(char pathline[],int size)
{
    snprintf(pathline,size,FORMAT,GetUserName(),GetHostName(),DirName(GetPwd()).c_str());
    // snprintf(pathline,size,FORMAT,GetUserName(),GetHostName(),GetPwd());
}

void CommandPrompt()
{
    char PatchLine[COMMAND_SIZE];
    GetPatchLine(PatchLine,sizeof(PatchLine));
    printf("%s",PatchLine);
   // fflush(stdout);
}

//2.识别用户输入的命令
bool GetCommadnLine(char* out,int size)
{
    char* s = fgets(out,size,stdin);
    if(s == nullptr) return false;
    out[strlen(out)-1] = 0;
    if(strlen(out) == 0) return false;
    return true;
}

//3.命令行解释  "ls -l -a" -> "ls" "-l" "-a"
void CommandTranslate(char* commandline)
{
#define seg " "
    g_argc = 0;
    g_argv[g_argc++] = strtok(commandline,seg);
    while((bool)(g_argv[g_argc++] = strtok(NULL,seg)));
    g_argc--;
}

//4.执行
int Execute()
{
    pid_t id = fork();

    if(id == 0)
    {
        execvp(g_argv[0],g_argv);
        exit(1);
    }

    pid_t rid = waitpid(id,nullptr,0);
    return 0;
}
int main()
{
    while(true)
    {
    //1.命令行提示符的创建
        CommandPrompt();
   
    //2.识别用户输入命令
        char CommandLine[COMMAND_SIZE];
        GetCommadnLine(CommandLine,sizeof(CommandLine));
    
    //3.命令解释
        CommandTranslate(CommandLine);

    //4.执行
        Execute();
    }
    return 0;
}
